package com.example.studykotlin.kotlin_actual_combat.art.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

public class BookMangerService extends Service {
    private static final String TAG = "BookMangerService";

    private AtomicBoolean mIsServiceDestroyed = new AtomicBoolean(false);


    public BookMangerService() {
    }

    private CopyOnWriteArrayList<Book> mBoolList = new CopyOnWriteArrayList<>();
    private RemoteCallbackList<IOnNewBookArrivedListener> mListenerList = new RemoteCallbackList<>();

    private Binder mBinder = new IBookManager.Stub() {
        @Override
        public List<Book> getBookList() throws RemoteException {
            SystemClock.sleep(5000);
            return mBoolList;
        }

        @Override
        public void addBook(Book book) throws RemoteException {
            mBoolList.add(book);
        }

        @Override
        public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
            Log.e(TAG, "registerListener: " );
            mListenerList.register(listener);
            final int N = mListenerList.beginBroadcast();
            mListenerList.finishBroadcast();
            Log.e(TAG, "registerListener, current size:" + N);
        }

        @Override
        public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
            boolean success = mListenerList.unregister(listener);

            if (success) {
                Log.e(TAG, "unregister success.");
            } else {
                Log.e(TAG, "not found, can not unregister.");
            }

            final int N = mListenerList.beginBroadcast();
            mListenerList.finishBroadcast();
            Log.e(TAG, "unregisterListener, current size:" + N);
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mBoolList.add(new Book(1,"Android"));
        mBoolList.add(new Book(2,"ios"));
        new Thread(new Servicework()).start();
    }

    @Override
    public void onDestroy() {
        mIsServiceDestroyed.set(true);
        super.onDestroy();
    }

    private void onNewBookArrived(Book book) throws RemoteException {
        mBoolList.add(book);
        final int N = mListenerList.beginBroadcast();
        Log.e(TAG, "onNewBookArrived notify listener:"+N );
        for (int i=0; i< N;i++) {
            IOnNewBookArrivedListener listener = mListenerList.getBroadcastItem(i);
            if (listener != null) {
                listener.onNewBookArrived(book);
            }
        }
        mListenerList.finishBroadcast();
    }

    private class Servicework implements Runnable {
        @Override
        public void run() {
            while (!mIsServiceDestroyed.get()) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int bookId = mBoolList.size() + 1;
                Book newBook = new Book(bookId,"new Book#" + bookId);
                try {
                    onNewBookArrived(newBook);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}